﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using VAdvantage.Model;
using VAdvantage.Utility;
using VAdvantage.Logging;
using System.Text;
using VAdvantage.Classes;

namespace VAdvantage.Panels
{
    public partial class TreeSearchPanel : UserControl,IStartMenuTree
    {

        VLogger log = VLogger.GetVLogger(typeof(TreeSearchPanel).FullName);

        #region Declaration
        //
        private int _windowNo;
        /** Tree ID                     */
        private int _AD_Tree_ID = 0;
        /** Table Name for TreeNode     */
        private String _nodeTableName = null;
        /** Tree is editable (can move nodes) - also not active shown   */
        private bool _editable;
        /** Tree has a shortcut Bar     */
        private bool _hasBar;
        /** The root node               */
        private VTreeNode _root = null;
        /* context*/
        private Ctx _ctx = Utility.Envs.GetCtx();
        /* menu Items */
       // private ToolStripMenuItem mnuItemMove;
      //  private ToolStripMenuItem mnuItemInsert;
       /// private ToolStripMenuItem mnuItemBar, mnuItemMenu;

        private VTreeNode _nodeFrom = null;
        private VTreeNode _nodeTo = null;

        private bool _isUpdating = false;

        private int maxLevel = 0;

        private VTreeNode _clickedNode = null;

        //public delegate void TreeNodeClick(Object sender, VTreeNodeEventArgs e);
        //public event TreeNodeClick FireNodeClick;

        #endregion

        /// <summary>
        /// std Constructor
        /// </summary>
        /// <param name="WindowNo"></param>
        /// <param name="hasBar"></param>
        /// <param name="editable"></param>
        public TreeSearchPanel(int WindowNo, bool hasBar, bool editable)
        {
            _windowNo = WindowNo;
            _hasBar = hasBar;
            _editable = editable;
            InitializeComponent();
            //LoadImageList();

           
            if (!hasBar)
            {
               // pnlCombo.Visible = false;
               // treeMenu.ContextMenuStrip = null;
            }
            else
            {
              //  AddItemsInComboBox();
               // SetContextMenuText();
               /// pnlCombo.Visible = true;
                //treeMenu.ContextMenuStrip = mnuStripMenu;
                //treeFavorite.ContextMenuStrip = mnuStripBar;
            }
            //  base settings
            if (editable)
            {
               // SetDragDropEvent();
               // SetEditableMenuItems();
               // SetLabelText();
               // treeMenu.ContextMenuStrip = mnuStripMenu;
               // treeMenu.AllowDrop = true;
               // btnMinus.Visible = true;
               // btnPlus.Visible = true;
                //pBoxSearch.Visible = false;
               // pBoxSearch.SendToBack();
            }
            //tree.setDropTarget(dropTarget);
            else
            {
                //popMenuTree.remove(mFrom);
                //popMenuTree.remove(mTo);
               // btnMinus.Visible = false;
              //  btnPlus.Visible = false;
               // pBoxSearch.Visible = true;
                
                //pBoxSearch.BringToFront();
               // SetLabelText();
               // flpnlSearch.Dock = DockStyle.Fill;
            }
        }   //  VTreePanel

        /// <summary>
        /// Init Tree
        /// </summary>
        /// <param name="AD_Tree_ID"></param>
        /// <returns></returns>
        public bool InitTree(int AD_Tree_ID)
        {
            log.Config("AD_Tree_ID=" + AD_Tree_ID);
            
            _AD_Tree_ID = AD_Tree_ID;

            MTree vTree = null;

            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {
                vTree = new MTree(Envs.GetCtx(), AD_Tree_ID, _editable, true, null);

                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(delegate
                {
                    vTree.PrepareNodes(this);

                    _root = vTree.GetRootNode();
                    //  SetMaxLevel(_root);
                    //log.config("root=" + m_root);
                    _nodeTableName = vTree.GetNodeTableName();
                    if (_root != null)
                    {
                        treeMenu.Items.Clear();
                        treeMenu.Items.Add(_root);
                    }
                    
                    //maxLevel = _root.getm
                    //  Shortcut Bar
                    if (_hasBar)
                    {
                        //treeFavorite.Nodes.Clear();	//	remove all existing buttons
                        //List<VTreeNode> lst = vTree.GetBarNodes();
                        //IEnumerator<VTreeNode> en = lst.GetEnumerator();
                        //while (en.MoveNext())
                        //{
                        //    VTreeNode nd = (VTreeNode)en.Current;
                        //    treeFavorite.Nodes.Add(nd);
                        //}
                    }

                });
            });
            return true;

        }   //  initTree

        /// <summary>
        /// selection changed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cmbSearch_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //throw new NotImplementedException();
        }

        private void TreeViewDragDropTarget_Drop(object sender, Microsoft.Windows.DragEventArgs e)
        {
            //e.Handled = true;
            //DependencyObject o = e.OriginalSource  as DependencyObject;

            //TreeViewItem dropNode = treeManager.GetItemContainerAncestor(treeMenu.Items[0] as ItemsControl, o);
            
            //object o1 = ((System.Windows.Controls.ItemDragEventArgs)(e.Data.GetData(typeof(System.Windows.Controls.ItemDragEventArgs)))).Data;

            //TreeViewItem movingNode = (((System.Collections.ObjectModel.SelectionCollection)o1)[0]).Item as TreeViewItem;
            //MoveNode((VTreeNode)movingNode, (VTreeNode)dropNode);
            
        }

        VTreeNode itemDestination = null;

      

        private void treeManager_DragOver(object sender, Microsoft.Windows.DragEventArgs e)
        {
            e.Effects = Microsoft.Windows.DragDropEffects.Move;

            //Second parts handles accessing item on which dragged items are dropped
            FrameworkElement frameworkElement = e.OriginalSource as FrameworkElement;

            DependencyObject o = VisualTreeHelper.GetParent(frameworkElement);

            while (o != null && o.GetType() != typeof(VTreeNode))
            {
                o = VisualTreeHelper.GetParent(o);
            }

            if (o != null)
            {
                itemDestination = ((VTreeNode)o);
                // TreeViewItem td = TTManager.GetItemContainerAncestor((ItemsControl)tt.Items[0], e.OriginalSource as DependencyObject);
                if (itemDestination == null || itemDestination.GetParentTreeViewItem() == null || !itemDestination.IsSummary)
                {
                    e.Effects = Microsoft.Windows.DragDropEffects.None;
                    e.Handled = true;
                }
            }
            else
            {
                e.Effects = Microsoft.Windows.DragDropEffects.None;
                e.Handled = true;
            }
        }

        private void treeManager_ItemDragStarting(object sender, ItemDragEventArgs e)
        {
            
        }

        private void treeManager_ItemDroppedOnSource(object sender, Microsoft.Windows.DragEventArgs e)
        {

        }

        private void treeManager_ItemDroppedOnTarget(object sender, ItemDragEventArgs e)
        {

        }

        private void treeManager_ItemDragCompleted(object sender, ItemDragEventArgs e)
        {

        }


        public TreeView vTreeView
        {
            get
            {
                return treeMenu;
            }
        }

        public void ItemClick(VTreeNode node)
        {
           // throw new NotImplementedException();
        }

        public void ItemRightClick(VTreeNode node, bool isFavorite)
        {
            //throw new NotImplementedException();
        }


       

        public void ItemRightClick(VTreeNode node, VTreeNode.ContextEventType e)
        {

            if(e.Equals(VTreeNode.ContextEventType.Cancel))
            {
                _nodeFrom = null;

            }
            if (e.Equals(VTreeNode.ContextEventType.Move))
            {
                _nodeFrom = node;
            }


            else if (e.Equals(VTreeNode.ContextEventType.Insert))
            {
                if (_nodeFrom != null)
                {

                    _nodeTo = node;
                    //if (_nodeFrom.Equals(_nodeFrom))
                    //{
                    //    return;
                    //}
                    MoveNode(_nodeFrom, _nodeTo);
                    //	cleanup
                     _nodeFrom = null;
                     _nodeTo = null;

                }
            }
        }

        private void MoveNode(VTreeNode movingNode, VTreeNode toNode)
        {
             log.Info(movingNode.ToString() + " to " + toNode.ToString());

            if (movingNode == toNode)
                return;

            Object selectedNode = treeMenu.SelectedItem;
            //treeMenu.SelectedItem = null;
            //  remove
            VTreeNode oldParent = (VTreeNode)movingNode.Parent;
            oldParent.Items.Remove(movingNode);// movingNode.removeFromParent();
            //treeModel.nodeStructureChanged(oldParent);
            //  insert
            VTreeNode newParent;
            int index;
            if (!toNode.IsSummary)	//	drop on a child node
            {
                newParent = (VTreeNode)toNode.Parent;

                index = newParent.Items.IndexOf(toNode) + 1;

                //index = toNode.GetDepth() + 1; // newParent.getIndex(toNode) + 1;	//	the next node
            }
            else									//	drop on a summary node
            {
                newParent = toNode;
                index = 0;                   			//	the first node
            }
            newParent.Items.Insert(index, (TreeViewItem)movingNode);

            treeMenu.Cursor = Cursors.Wait;

            List<String> queries = new List<String>();


            for (int i = 0; i < oldParent.Items.Count; i++)
            {
                VTreeNode nd = (VTreeNode)oldParent.Items[i];
                StringBuilder sql = new StringBuilder("UPDATE ");
                sql.Append(_nodeTableName)
                    .Append(" SET Parent_ID=").Append(oldParent.Node_ID)
                    .Append(", SeqNo=").Append(i)
                    .Append(", Updated=SysDate")
                    .Append(" WHERE AD_Tree_ID=").Append(_AD_Tree_ID)
                    .Append(" AND Node_ID=").Append(nd.Node_ID);
                log.Fine(sql.ToString());
                queries.Add(sql.ToString());
                //DataBase.DB.ExecuteQuery(sql.ToString(), null, trx.GetTrxName());
            }
            if (oldParent != newParent)
                for (int i = 0; i < newParent.Items.Count; i++)
                {
                    VTreeNode nd = (VTreeNode)newParent.Items[i];
                    StringBuilder sql = new StringBuilder("UPDATE ");
                    sql.Append(_nodeTableName)
                        .Append(" SET Parent_ID=").Append(newParent.Node_ID)
                        .Append(", SeqNo=").Append(i)
                        .Append(", Updated=SysDate")
                        .Append(" WHERE AD_Tree_ID=").Append(_AD_Tree_ID)
                        .Append(" AND Node_ID=").Append(nd.Node_ID);
                    log.Fine(sql.ToString());
                    queries.Add(sql.ToString());
                    //DataBase.DB.ExecuteQuery(sql.ToString(), null, trx.GetTrxName());
                }

            _isUpdating = true;
            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {

                VAdvantage.DataBase.Trx trx = VAdvantage.DataBase.Trx.Get("VTreePanel", true);

                try
                {
                    DataBase.DB.ExecuteMultipleQueries(queries, trx.GetTrxName());
                    trx.Commit();
                }
                catch (Exception e)
                {
                    trx.Rollback();
                    log.Log(Level.SEVERE, "move", e);
                    ShowMessage.Error("TreeUpdateError", null, e.Message);
                }

                if (trx != null)
                {
                    trx.Close();
                    trx = null;
                }
                _isUpdating = false;
                log.Config("complete");
                Dispatcher.BeginInvoke(()=>treeMenu.Cursor = Cursors.Arrow);
            });

            if (_nodeFrom != null)
            {
                _nodeFrom = null;
            }
            maxLevel = 0;  //reset max level

            //SetMaxLevel((VTreeNode)treeMenu.Nodes[0]);
            if (selectedNode != null)
            {
                //treeMenu.SelectedNode = selectedNode;
                //selectedNode = null;
            }
        }

        public void ItemContextEvent(VTreeNode node,bool isClosed)
        {
            if (isClosed)
            {
                node.CopyItem.IsEnabled = true;
                node.PasteItem.IsEnabled = true;
                node.CancelItem.IsEnabled = true;
            }
            else
            {

                if (_isUpdating)
                {
                    node.CopyItem.IsEnabled = false;
                    node.PasteItem.IsEnabled = false;
                    node.CancelItem.IsEnabled = false;
                    return;
                }

                if (_nodeFrom != null)
                {
                    node.CopyItem.IsEnabled = false;
                    if (_nodeFrom == node)
                    {
                        node.PasteItem.IsEnabled = false;
                    }
                    else
                    {
                        node.PasteItem.IsEnabled = true;
                    }
                    node.CancelItem.IsEnabled = true;
                }
                else
                {
                    node.CopyItem.IsEnabled = true;
                    node.PasteItem.IsEnabled = false;
                    node.CancelItem.IsEnabled = false;
                }
            }
        }

        public void NodeChanged(bool save, int keyID,
            String name, String description, bool isSummary, String imageIndicator)
        {
            log.Config("Save=" + save + ", KeyID=" + keyID
                + ", Name=" + name + ", Description=" + description
                + ", IsSummary=" + isSummary + ", ImageInd=" + imageIndicator
                + ", root=" + _root);
            	//if ID==0=root - don't update it
            if (keyID < 0)
                return;
            //  try to find the node
            VTreeNode node = _root.FindNode(keyID);
            ////  Node not found and saved -> new
            if (node == null && save)
            {
                node = new VTreeNode(keyID, 0, name, description, _root.Node_ID, isSummary, imageIndicator, false,this,_editable);
                _root.Items.Add(node);
            }
            //  Node found and saved -> change
            else if (node != null && save)
            {
                node.SetName = name;
                node.ToolTipText = description;
                node.SetSummary(isSummary);
                if (isSummary)
                {
                    node.ImageKey = "C";
                    //node.SelectedImageKey = "C";
                }
                else
                {
                    node.ImageKey = imageIndicator;
                    //node.SelectedImageKey = imageIndicator;
                }
                //node.setAllowsChildren(isSummary);
            }
            //  Node found and not saved -> delete
            else if (node != null && !save)
            {
                VTreeNode parent = (VTreeNode)node.Parent;
                parent.Items.Remove(node); //node.removeFromParent();
                node = parent;  //  select Parent
            }
            //  Error
            else
            {
                log.Log(Level.SEVERE, "Save=" + save + ", KeyID=" + keyID + ", Node=" + node);
                node = null;
            }
            //  Nothing to display
            if (node == null)
                return;

            ////  (Re) Display Node
            //tree.updateUI();
            //TreePath treePath = new TreePath(node.getPath());
            //tree.setSelectionPath(treePath);
            //node.IsSelected = true;// tree.makeVisible(treePath);       	//	expand it

            //tree.scrollPathToVisible(treePath);
        }


        PreorderEnumerator en = null;
        private void txtSearch_KeyUp(object sender, KeyEventArgs e)
        {
            if (txtSearch.Text != "")
            {
                //if user press enter key
                if (e.Key == Key.Enter)
                {
                    //if (e.Modifiers != Keys.None)
                    //{
                    //    _clickedNode = (VTreeNode)treeMenu.SelectedNode;
                    //    StartAction();
                    //}
                    //else
                    //{
                    int index =0;
                    if (en == null)
                    {
                        en = new PreorderEnumerator((TreeViewItem)treeMenu.Items[0]);
                    }
                    else
                    {
                        en.Reset();
                    }


                    VTreeNode selectedNode = null;
                    while (en.MoveNext())
                    {
                        VTreeNode tn = (VTreeNode)en.Current;
                        if (en.isLast)
                        {
                            iStoredIndex = 0;
                        }
                        if (tn.GetName.ToLower().Contains(txtSearch.Text.ToLower()))
                        {
                            
                            if (index <= iStoredIndex)
                            {
                                continue;
                            }
                            selectedNode = tn;
                            break;
                        }
                        index++;
                    }
                   
                    if (selectedNode != null)
                    {
                        iStoredIndex = index;
                        DependencyObject node = selectedNode.Parent;
                        while (node != null)
                        {
                            ((TreeViewItem)node).IsExpanded = true;

                            if (((TreeViewItem)node).Parent is TreeViewItem)
                            {
                                node = ((TreeViewItem)node).Parent;
                            }
                            else node = null;
                        }
                        //tree.vTreeView.SelectItem(myTreeNode);


                        Dispatcher.BeginInvoke(delegate
                        {
                           // isPostionSetting = true;
                            ((TreeViewItem)selectedNode).IsSelected = true;
                            //myTreeNode = null;
                            //isPostionSetting = false;

                        });
                    }

                        //iIndex = 0;
                        //// Call The recursive function
                        //TreeNode tn = FindRecursive(treeMenu, treeMenu.Nodes, txtSearch.Text.Trim().ToLower());
                        //if (tn != null)
                        //{
                        //    tn.EnsureVisible();
                        //    treeMenu.SelectedNode = tn;
                        //    currentLevel = tn.Level;
                        //}
                        //else if (treeMenu.SelectedNode == null)
                        //{
                        //    treeMenu.SelectedNode = null;
                        //}
                    //}
                }
                //if other key is pressed
               // else
               // {
                 //   iIndexStrored = 0;
                //}

            }
        }

        int iStoredIndex = 0;
        private void txtSearch_TextChanged(object sender, TextChangedEventArgs e)
        {
            iStoredIndex = 0;
            if (en != null)
            {
                en.Dispose();
                en = null;
            }
        }   
    }
}
